package com.g2room.driving.grap.life;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.jetty.util.StringUtil;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.alibaba.fastjson.JSON;
import com.g2room.driving.grap.GenericGrap;
import com.g2room.driving.grap.life.model.po.ComShopComment;
import com.g2room.myuall.grap.ky.model.po.GrapErr;
import com.g2room.myuall.util.DbUtil;

public class GrabCtripComment implements Runnable {
	public static String baseUrl = "http://you.ctrip.com";
	public static final String listUrl = "http://you.ctrip.com/destinationsite/TTDSecond/SharedView/AsynCommentView?districtEName=Chongqing&districtId=158&order=3&pagenow=#p#&poiID=#poi#&resourceId=#r#&resourcetype=#t#&star=0&tourist=0";
	private Map<Integer, String> ids = new HashMap<Integer, String>();
	private String type = null;
	private String typeName = null;
	@Override
	public void run() {
		if(ids == null) return;
		for(int id : ids.keySet()) {
			getList(type, typeName, id, ids.get(id));
		}
	}
	public GrabCtripComment(String type, String typeName) {
		this.type= type;
		this.typeName = typeName;
	}
	
	public static void main(String[] args) throws Exception{
		Map<String, String> types = new HashMap<String, String>();
//		types.put("2", "美景"); // 美景
		types.put("3", "美食"); // 美食
		types.put("4", "购物"); // 美食
		//#p#&type=#t#&resource=#r#&writing=&rand=0.#rand#
		for(String t : types.keySet()) {
			System.out.println(t + "==" + types.get(t));
			Map<Integer, String> urls = getUrls(t);
			Map<Integer, String> tids = new HashMap<Integer, String>();
			for(int id : urls.keySet()) {
				tids.put(id,  urls.get(id));
				if(tids.size() == 100) {
					GrabCtripComment gkd = new GrabCtripComment(t, types.get(t));
					gkd.ids.putAll(tids);
					Thread thread = new Thread(gkd);
					thread.start();
					tids.clear();
				}
			}
			
			if(tids.size() > 0) {
				GrabCtripComment gkd = new GrabCtripComment(t, types.get(t));
				gkd.ids.putAll(tids);
				Thread thread = new Thread(gkd);
				thread.start();
				tids.clear();
			}
		}
    }
	
	public void getList(String type, String typeName, int id, String surl) {
		// 获取poiId
		Document doc = null;
		try {
			doc = GenericGrap.getDocumentByIp(surl);
		} catch (IOException e) {
			GrapErr ge = new GrapErr();
			ge.setUrl(surl);
			ge.setType("1");
			ge.setContent(type+"="+typeName);
			ge.setDescription("获取Imgs错误：" + e.getMessage());
			insert2ErrDb(ge);
			return;
		}
		Elements els = doc.select(".b_orange_m");
		if(null == els || els.isEmpty()) return;
		String poi = els.first().attr("href");
		poi = poi.substring(poi.lastIndexOf("/") + 1).replace(".html", "");  ///dianping/edit/10558680.html
		for(int i=1; i< 101; i++) {
			try {
				/**
				 * &pagenow=#p#&poiID=#poi#&resourceId=#r#&resourcetype=#t#
				 */
				System.out.print("\n开始抓取:" + typeName + ",id="+id +",poi=" + poi +",p=" + i);
				String url = listUrl.replace("#p#", i+"").replace("#t#", type).replace("#poi#", poi).replace("#r#", id+"");
				if(!getComment(url, typeName, id, type)) {
					System.out.println("抓取完毕");
					break;
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	public boolean getComment(String url, String tn, int id, String type) {
		Document doc = null;
		try {
			doc = GenericGrap.getDocumentByIp(url);
		} catch (IOException e) {
			GrapErr ge = new GrapErr();
			ge.setUrl(url);
			ge.setType("2");
			ge.setContent(id+"");
			ge.setDescription("获取comment错误：" + e.getMessage());
			insert2ErrDb(ge);
			return true;
		}

		if (null == doc) return true;
		try {
			Elements els = doc.select("div.comment_single");
			if(null == els || els.isEmpty()) return false;
			List<ComShopComment> cscs = new ArrayList<ComShopComment>();
			for(Element el : els) {
				ComShopComment csc = new ComShopComment();
				Elements tempEls = el.select(".userimg a img");
				String text = null;
				if(null != tempEls && !tempEls.isEmpty()) {
					text = tempEls.first().attr("src");
					if(!text.contains("http://images4.c-ctrip.com/target/headphoto/portrait_100_100.jpg")) csc.setHead(tempEls.first().attr("src"));
				}
				tempEls = el.select(".userimg span a");
				if(null != tempEls && !tempEls.isEmpty()) {
					text = tempEls.first().text();
					csc.setUsername(text.contains("携程用户")?null:text);
				}

				tempEls = el.select(".sblockline");
				if(null != tempEls && !tempEls.isEmpty()) {
					text = tempEls.first().text();
					if(StringUtil.isNotBlank(text)) {
						String[] ss = text.split("  ");
						for(String str : ss) {
							//景色：5  趣味：5  性价比
							if(!type.equals("3")) {
								System.out.println(text);
							}
							if(str.contains("口味") || str.contains("商品") || str.contains("景色")) {
								csc.setFlavor(str.replace("口味：", "").trim());
							} else if(str.contains("环境") || str.contains("趣味")) {
								csc.setEnvironment(str.replace("环境：", "").trim());
							} else if(str.contains("性价比") || str.contains("服务")) {
								csc.setServer(str.replace("服务：", "").trim());
							}
						}
					}
				}
				
				// 评论内容
				tempEls = el.select(".heightbox");
				if(null != tempEls && !tempEls.isEmpty()) {
					csc.setContent(tempEls.first().html());
				}
				
				// 评论图片
				tempEls = el.select("li.comment_piclist a");
				if(null != tempEls && !tempEls.isEmpty()) {
					String hrefs = "";
					for(Element ael : tempEls) {
						if(hrefs.length() > 1) hrefs += ";";
						hrefs += ael.attr("href");
					}
					csc.setImages(hrefs);
				}
				
				// 评论时间
				tempEls = el.select("span.time_line");
				if(null != tempEls && !tempEls.isEmpty()) {
					csc.setCommentTime(tempEls.first().text());
				}
				csc.setShopId(id);
				csc.setKindName(tn);
				cscs.add(csc);
			} 
			if(null == cscs || cscs.size()>0) insert2CommentDb(cscs);
			return true;
		} catch (Exception e) {
			GrapErr ge = new GrapErr();
			ge.setUrl(url);
			ge.setType("3");
			ge.setContent(id+"");
			ge.setDescription("获取Detail错误：" + e.getMessage());
			insert2ErrDb(ge);
			return true;
		}
	}
	
	public void insert2CommentDb(List<ComShopComment> cscs) {
		String sql = "insert into life_comment(username,images,spend_perhead,shop_name,star,environment,content,head,server,comment_time,flavor,shop_id,kind_name) values(?,?,?,?,?,?,?,?,?,?,?,?,?)";
		PreparedStatement ps = null;
		try {
			ps = DbUtil.getComConn().prepareStatement(sql);
			for(ComShopComment cc : cscs) {
				ps.setString(1, getUtf8Str(cc.getUsername()));
				ps.setString(2, cc.getImages());
				ps.setString(3, cc.getSpendPerhead());
				ps.setString(4, cc.getShopName());
				ps.setString(5, cc.getStar());
				ps.setString(6, getUtf8Str(cc.getEnvironment()));
				ps.setString(7, getUtf8Str(cc.getContent()));
				ps.setString(8, cc.getHead());
				ps.setString(9, getUtf8Str(cc.getServer()));
				ps.setString(10, cc.getCommentTime());
				ps.setString(11, getUtf8Str(cc.getFlavor()));
				ps.setInt(12, cc.getShopId());
				ps.setString(13, cc.getKindName());
				ps.addBatch();
			}	
			ps.executeBatch();	
		} catch (Exception e) {
			e.printStackTrace();
			GrapErr ge = new  GrapErr();
			ge.setType("5");
			ge.setContent(JSON.toJSONString(cscs));
			ge.setDescription("插入Detail错误："+e.getMessage());
			insert2ErrDb(ge);
			return;
		} finally {
			if(null != ps) {
				try {
					ps.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	private String getUtf8Str(String str) {
		try {
			str = null == str ? null : new String(str.getBytes(), "utf-8").replaceAll("[\\ud83c\\udc00-\\ud83c\\udfff]|[\\ud83d\\udc00-\\ud83d\\udfff]|[\\u2600-\\u27ff]", "");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return str;
	}

	public void insert2ErrDb(GrapErr ge) {
		PreparedStatement grapPs = null;
		try {
			grapPs = DbUtil.getComConn().prepareStatement("insert into grap_err(description,url,content,type) values(?,?,?,?)");
			grapPs.setString(1, ge.getDescription());
			grapPs.setString(2, ge.getUrl());
			grapPs.setString(3, ge.getContent());
			grapPs.setString(4, ge.getType());
			grapPs.execute();
			grapPs.close();
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			if(null != grapPs) {
				try {
					grapPs.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}
	public static List<GrapErr> getErrs() {
		List<GrapErr> univs = new ArrayList<GrapErr>();
		try {
			Connection connection = DbUtil.getComConn();
			Statement statement = connection.createStatement();
			String sql = "select * from grap_err";
			ResultSet rs = statement.executeQuery(sql);
			while(rs.next()) {
				GrapErr univ = new GrapErr();
				univ.setId(rs.getInt("id"));
				univ.setUrl(rs.getString("url"));
				univ.setType(rs.getString("type"));
				univ.setContent(rs.getString("content"));
				univs.add(univ);
			}
			rs.close();
			statement.close();
		} catch(Exception e) {
			e.printStackTrace();
		}
		return univs;
	}
	
	public static void delErr(int id) {
		PreparedStatement grapPs = null;
		try {
			grapPs = DbUtil.getComConn().prepareStatement("delete from grap_err where id=?");
			grapPs.setInt(1, id);
			grapPs.execute();
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			if(null != grapPs) {
				try {
					grapPs.close();
				} catch (SQLException e) {
					
				}
			}
		}
	}
	
	public static Map<Integer, String> getUrls(String type) {
		Map<Integer, String> map =new HashMap<Integer, String>();
		try {
			Connection connection = DbUtil.getComConn();
			Statement statement = connection.createStatement();
			String sql = "select  old_id,source_url from life_scenery";
			if(type.equals("2")) {
				sql = "select  old_id,source_url from life_scenery";
			} else if(type.equals("3")) {
				sql = "select  old_id,source_url from com_shop where kind_name='餐馆美食' or kind_name='餐馆小吃'";
			} else if(type.equals("4")) {
				sql = "select  old_id,source_url from com_shop where kind_name='购物'";
			}
			
			ResultSet rs = statement.executeQuery(sql);
			while(rs.next()) {
				map.put(rs.getInt("old_id") ,rs.getString("source_url"));
			}
			rs.close();
			statement.close();
		} catch(Exception e) {
			e.printStackTrace();
		}
		return map;
	}
	
}
